呦~這篇是延續上一篇,若還沒看過上一篇可以先看過再過來喔。
Nix 是跨平台的套件與環境管理器,能在 Linux、macOS 與 WSL 保持開發環境一致;Flake 則是 Nix 的現代化配置方式,有點像 lockfile,用來精確定義專案需要哪些工具(例如 Node、pnpm、Bun,甚至 Postgres 與 Redis)、固定使用的版本,以及如何以可重現的方式建構整個環境。
多人團隊常見的痛點是「我的電腦可以跑,同事的電腦卻跑不起來」。設定好 flake.nix 後,無論在 macOS 或 Linux,只要執行 nix develop,大家取得的工具與依賴版本都會一致。這對長期維護、多人協作,或需要可重現建置的專案特別有幫助。
如果只是想快速體驗 Effect,沒有要跟別人協作,只是想在自己 local 的電腦玩一玩,不一定需要 Nix,也可以不用繼續閱讀這篇文章。但如果你打算維護大型專案,且合作的開發者會橫跨多個平台(例如有人用 Mac、有人用 Linux),很建議了解一下。總之我能力有限。我深知一個人是很難幹大事的,所以還是來學習一下。如果你跟我想的一樣,那就繼續看下去吧!
# 安裝 nix
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
# 你會遇到`nix-installer` needs to run as `root`, attempting to escalate now via `sudo`...
# 你再輸入你管理員身份的密碼
# 再來你會遇到
# Install Determinate Nix?
# It has stable flakes, lazy trees, parallel evaluation, and more.
# Selecting 'no' will install upstream Nix, which comes from NixOS.org.
# 這是安裝程式在詢問你要不要安裝「Determinate Nix」(加強過的 macOS 版 Nix)。選擇 no 則安裝「上游 Nix」(NixOS 官方原版)。
# 但這裡建議選擇 yes(安裝 Determinate Nix):開箱支援 flakes、在 macOS(含 Apple Silicon)整體更穩健。
# 接下來你會遇到 Planned actions 的確認。就都選擇 yes 就行了
在你安裝好後,請重新開啟你的 terminal,並且執行 nix --version,你會看到類似下面的輸出:
nix (Determinate Nix 3.11.2) 2.31.1
這就代表你成功安裝了 nix。接下來讓我們看看 flake 是不是也成功安裝了。
nix flake show
# 執行 nix flake show 會 解析 flake 的依賴 → 更新或建立 lock file。
# 這是因為 Nix 需要把輸出列出來,就必須先「確定依賴是哪些準確版本」。
# 所以你在目錄中會看到一個新的檔案 `flake.lock`。它就像 pnpm-lock.yaml 或 package-lock.json 一樣,記錄所有依賴的準確版本。
terminal 會列出這個 flake 定義的 devShells、formatter 等資訊。它只是「顯示」flake 的結構,適合摸清楚 flake 提供了什麼。如果你也看到類似的東西,就代表你成功安裝了 flake。順便一提,你可能會發現為何 nix flake 相關的套件為何沒有在 package.json 裡,那是因為 Nix 是系統層的工具。package.json 只管 Node 的相依套件與腳本。
回到我們的專案根目錄,你會看到兩個在初始化專案後,檔案就存在,且內容與 nix flake 有關。一個是 flake.nix,另一個是 .envrc。我們來一一介紹它們。
flake.nix{ # 這是一個 Nix flake 的主體(像是一份可重複、可分享的「開發環境食譜」)
inputs = { # 定義這個 flake 需要哪些依賴
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; # 這裡選了 nixpkgs 的一個更新較快的版本,代表我們要的軟體都從這個來源取得。
};
outputs = {nixpkgs, ...}: let # 定義最後輸出什麼東西
forAllSystems = function: # 小工具:幫你把同一份設定,套到「所有支援的系統(作業系統/架構)」上
nixpkgs.lib.genAttrs nixpkgs.lib.systems.flakeExposed
(system: function nixpkgs.legacyPackages.${system}); # 對每個 system 取出對應的套件集合 pkgs,然後執行 function
in { # 這裡開始是「實際的輸出樣子」
formatter = forAllSystems (pkgs: pkgs.alejandra); # 給每個系統都準備同一個程式碼格式化器「alejandra」
devShells = forAllSystems (pkgs: { # 給每個系統都準備一個「開發用的 Shell 環境」
default = pkgs.mkShell { # 預設的開發 Shell(你進來就會有下面這些工具)
packages = with pkgs; [ # 進入這個 Shell 之後,自動能用的軟體清單
corepack # 啟用 Node 的套件管理器(讓你方便用 yarn/pnpm)
nodejs_22 # 指定 Node.js 版本 22(每個人都用同一版本,避免版本地獄)
# For systems that do not ship with Python by default (required by `node-gyp`)
python3 # 提供 Python,因為 node-gyp(某些 Node 原生模組)在建置時需要它
];
};
});
};
}
.envrc內容如下:
use flake
cd 進專案資料夾時,自動載入 Nix flake 定義的開發環境(你的 flake.nix 裡的 devShells.default:Node.js 22、Corepack、Python 3)。nix develop;環境自動啟用、離開資料夾自動還原。現在我們了解完 專案中 nix flake 相關的檔案內容。接下來我們來設定 direnv(自動載入開發環境)。
# 我是用 mac 的,再請用 windows 的大哥哥大姐姐們找一下適合你們的方法。
brew install direnv
direnv allow
# 嘗試 cd 進專案目錄,看看是否可以正常載入開發環境。
cd /Users/eric/personal-project/effect-app
# 驗證一下你有自動起開發環境。
which node
# 結果:/nix/store/3scj3c1qxh5iclf8jy5hbl9pki40y77n-nodejs-22.19.0/bin/node
# 你會看到 nix 開頭的 node 的路徑,這就代表你成功載入開發環境。
我們透過 Create Effect App CLI 建置專案,並根據預設建議配置說明了 Changesets、GitHub Actions 與 Nix flake 的使用方法。我們再快速複習一下:
今天這篇比較短🫣,明天我再加油💪~